package org.seedltd.upms.controller.common;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

import org.seedltd.base.exception.BusinessException;
import org.seedltd.base.exception.ParamsInvalidException;
import org.seedltd.core.base.BaseEnum;
import org.seedltd.core.model.EnumVO;
import org.seedltd.core.utils.Assert;
import org.seedltd.core.utils.StringUtils;
import org.seedltd.core.utils.WebUtils;
import org.seedltd.oss.service.IOssService;
import org.seedltd.upms.constant.FolderBucket;
import org.seedltd.upms.constant.GlobalConst;
import org.seedltd.upms.model.sys.entity.SysAttachment;
import org.seedltd.upms.service.sys.SysAttachmentService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Lists;

/**
 *
 * 通用的控制层
 * 
 * @author laizuan
 * @version 1.0
 * @since 2021/7/22 18:08
 */
@RestController
public class CommonController {
    private final SysAttachmentService sysAttachmentService;
    private final IOssService ossService;

    @Value("${server.servlet.context-path:'/'}")
    private String name;

    public CommonController(SysAttachmentService sysAttachmentService, IOssService ossService) {
        this.sysAttachmentService = sysAttachmentService;
        this.ossService = ossService;
    }

    /**
     * 删除附件
     * 
     * @param id
     *            附件主键
     * @param linkedId
     *            关联主键
     * @return 是否删除成功
     */
    @GetMapping("/deleteAttachment/{id}/{linkedId}")
    public boolean deleteAttachment(@PathVariable Long id, @PathVariable Long linkedId) {
        Assert.notNull(id, "确少参数");
        Assert.notNull(linkedId, "确少参数");
        return sysAttachmentService.delete(id, linkedId, true);
    }

    /**
     * 删除附件
     *
     * @param bucket
     *            桶名称
     * @param path
     *            文件路径
     * @param response
     *            响应流
     * @param preview
     *            1预览，0下载
     * @throws IOException
     *             异常
     */
    @GetMapping("/download/attachment/{preview}/{bucket}")
    public void loadAttachment(HttpServletResponse response, @PathVariable Integer preview, @PathVariable String bucket,
        String path) throws IOException {
        FolderBucket folderBucket = FolderBucket.getByBuckName(bucket);
        byte[] bytes = ossService.download(folderBucket, path);
        WebUtils.setResponse(response, StringUtils.uuid() + path.substring(path.indexOf(".")), bytes,
            GlobalConst.YES.equals(preview));
    }

    /**
     * 上传文件
     * 
     * @param file
     *            文件名称
     * @return 文件路径
     */
    @PostMapping("uploadAttachment")
    public String uploadAttachment(MultipartFile file) throws IOException {
        Long id = sysAttachmentService.add(file, 0L, FolderBucket.OTHERS.getBucketName());
        Assert.notNull(id, "文件上传失败");
        return String.format("%s/attachment/1/%s", name, id);
    }

    /**
     * 预览或下载文件
     * 
     * @param id
     *            附件主键
     * @param response
     *            响应流
     * @param preview
     *            1预览，0下载
     * @throws IOException
     *             异常
     */
    @GetMapping("/attachment/{preview}/{id}")
    public void loadAttachment(@PathVariable Long id, HttpServletResponse response, @PathVariable Integer preview)
        throws IOException {
        Assert.notNull(id, "确少参数");
        SysAttachment attachment = sysAttachmentService.findById(id);
        Assert.notNull(attachment, "未找到文件");
        FolderBucket bucket = FolderBucket.getByBuckName(attachment.getBucket());
        byte[] bytes;
        try {
            bytes = ossService.download(bucket, attachment.getPath());
        } catch (FileNotFoundException e) {
            throw new BusinessException("【%s】存储桶中的【%s】文件不存在", attachment.getBucket(), attachment.getFileName());
        }
        WebUtils.setResponse(response, attachment.getFileName(), bytes, GlobalConst.YES.equals(preview));
    }

    /**
     * 获取静态枚举列表
     *
     * @param className
     *            静态枚举类名，注意区分大小写
     * @return 静态枚举列表
     */
    @GetMapping("/enum/static/{className}")
    public List<EnumVO> getEnumList(@PathVariable @NotNull(message = "类名不能为空") String className) {
        try {
            Class<?> clazz = Class.forName(String.format("org.seedltd.upms.enums.%s", className));
            if (BaseEnum.class.isAssignableFrom(clazz)) {
                BaseEnum[] baseEnums = (BaseEnum[])clazz.getEnumConstants();
                List<EnumVO> enumList = Lists.newArrayListWithExpectedSize(baseEnums.length);
                EnumVO enumVO = null;
                for (BaseEnum baseEnum : baseEnums) {
                    enumVO = new EnumVO(baseEnum.getValue().toString(), baseEnum.getDesc());
                    enumList.add(enumVO);
                }
                return enumList;
            } else {
                throw new ClassNotFoundException();
            }
        } catch (ClassNotFoundException e) {
            throw new ParamsInvalidException("无效类名");
        }
    }

}
